第五章 任务对话
很多时候,终端用户与机器人交互的目的并不只是获取一个常见问题的答案(这种简单任务可以通过一问一答来实现,具体说明请见[问答对话]。
终端用户的交互目的可能会很复杂。例如,用户通过机器人“查询订单状态”时,要想满足用户的这一目的,首先,机器人需要了解用户的”意图“;然后,机器人需要采取一些对话动作、获取完成这个意图所需的必要信息(比如,订单号,下单时间等);最后,用获取的信息完成任务。这往往需要多轮交互才能实现。
本平台的任务对话就提供了搭建多轮交互机器人的功能。
5.1 任务对话的核心能力
任务对话有三个重要能力:意图识别、实体抽取、对话管理。这每一个都由一个核心模块来完成:
1 意图识别:在用户发送第一句话后,机器人判断用户想表达的意图,并启动相应的任务流程。
- 比如:用户说“帮我定明天到上海的火车票”。机器人判断用户的意图为“订车票”。
- 在平台中,你可以通过设置意图的触发器来教机器人进行意图识别。
2 实体抽取:从用户的每一句话中,机器人尝试收集完成任务所需要的信息。
- 比如:用户说“帮我定明天到上海的火车票”。机器人可抽取到关键信息“目的地=上海”,和“出发日期=明天”。
- 在平台中,你可以通过创建实体和词槽、并在意图的对话单元中关联词槽来教机器人进行实体抽取。
3 对话管理:根据抽取到的关键信息,机器人判断接下来应该执行什么操作。
- 比如:用户说“帮我定明天到上海的火车票”之后,机器人知道了目的地和出发日期,那么可以判断接下来只需要询问出发地和出发时间。
- 你可通过在意图流程中创建对话单元以及对话单元之间的跳转关系来教机器人如何进行对话管理。
5.2任务对话的简要搭建步骤
1 首先创建一个[场景]。
2 在这个场景中,创建一个[意图]。
3 在创建意图的过程中,需要创建[触发器]、[词槽]、[对话单元]。
4 在创建意图的过程中,平台提供可视化的画布来搭建意图。如果你对画布的操作方式有疑问,可以参考[对话单元]。
5 在完成以上重要组件的创建之后,你需要使用[调试机器人]对任务对话进行测试。
6 可选步骤: 在某些情况下,你可能需要创建[填槽句式],来精细化管理意图填槽的顺序。
5.3场景
当你的任务对话有多个意图,其中一些意图彼此联系、共同完成一件事情时,你可以使用“场景”来管理这些意图。
场景是介于任务对话和意图之间的层级。场景可以用来管理彼此联系的一系列“意图”。
比如,你希望搭建一个票务机器人,按照场景分类,他需要完成“订票”、“退改签”、“增值服务“三件事情。这三件事情就分别对应三个”场景“。 在场景“订票”中可能包括的意图为”询问行程“、“订火车票”、“订飞机票”等。
新建场景
1 点击新建场景卡片。
2 在弹窗内选择新建。
3 设置场景名称、描述。
4 设置场景级别的配置项,通常情况下可保留默认值。设置项的具体含义如下:
回退到上一步话术:管理用户回退到上一步时,是否允许回退到单元或单元前的对话节点。
允许回退的效果:会话经过此单元后,用户的回复匹配到了设置的回退关键词。
- 机器人可以回退到他或他之前的对话节点,重新询问上一节点的问题。
禁止回退的效果:会话经过此单元后,用户的回复匹配到了设置的回退关键词。
- 机器人不能回退到他或之前的对话节点,机器人会回复失败话术并再次重复当前问题。
退出话术:管理用户在当前对话单元时,是否允许退出意图。
允许退出的效果:会话停留在这个单元的时候,用户的回复匹配到了设置的退出关键词。
- 机器人退出任务成功,回复配置的退出成功话术,引导用户重新开启对话。
禁止退出的效果:会话停留在这个单元的时候,用户的回复匹配到了设置的退出关键词。
- 机器人退出任务失败,机器人重复当前问题。
- 闲置等待时长:场景级别的闲置等待时间。
- 默认值为10分钟。
- 适用于该场景下所有意图。
- 当场景和意图两个级别都设置了闲置等待时间,取最小值作为当前意图的闲置等待时间。
- 关于“闲置等待”机制的一些常见情形的效果,参见[意图管理]。
- 智能填槽阈值:场景级别的智能填槽技术的阈值
- 默认值为0.7。
- 适用于该场景下所有词槽。
- 自动添加预置回复:当询问单元运行时,以如下勾选的方式,给用户推荐“可回复的内容”。
- 依据当前用户的历史回复推荐。
- 依据所有用户的高频回复推荐。
- 依据词槽引用的实体值推荐。
- 自动添加的预知回复最多5个,最少1个。
- 如果一个对话单元已经自定义了预置回复按钮,则只展示自定义的预置回复按钮,而不再自动推荐回复选项。
5 点击确定。
6 点击场景卡片,即可进入这个场景下的意图列表。
注意:
- 退出失败的时候,当前单元会算一次消耗次数。即如果这个单元设置了依次回复多种询问话术,并禁止在当前询问单元退出。当用户仍旧选择退出时,机器人将会使用下一个话术进行再次询问。 回退失败时,单元算一次消耗次数;成功时,单元状态重置,不算消耗次数。意图的结束单元可以允许回退,但如果超出了闲置等待时长,可能导致意图记录被清空,而回退失败。
建议禁止的情况:
- 由于业务逻辑导致回退会报错:
- 如写表单元新增行,回退导致相同的主体值重复新增,写入失败
- 场景设定某个提问不允许回退:
- 如询问填槽单元,不希望用户在某个单元回退
导入场景文件
1 点击新建场景卡片。
2 在弹窗内选择导入。
3 点击选择文件,选择一个从吾来平台上导出的未经修改的.taskbot文件。
4 点击确定,即可完成导入。
提示: 导入时如果相关资源(比如,实体、用户属性等)已经存在,会自动引用。
导出场景文件
当你需要将一个场景整体复制时,你可以导出已有场景并导入到一个新场景中。场景导出后保存在.taskbot文件中。
1 点击导出图标。
2 在导出完成后的提示中,点击下载文件。
提示: 导出时,会将场景中的意图、词槽、填槽句式、以及词槽引用的实体全部导出。
5.4意图
机器人要想帮助用户完成一些复杂任务,首先要了解用户到底想要什么。这里,用户想要的事情,称之为“意图”。
举个例子,当用户想要机器人帮他订一张机票时,用户说“给我订一张从北京到上海的MU3205”。用户说这句话的意图就是“订机票”。
意图与其他概念的关系
用”高内聚、低耦合“的设计思想来搭建一个任务型对话,通常是一个很好的选择。此时,
一个任务型对话,由多个”意图“构成。
每个”意图“ 由触发器和关联到该意图的”流程“共同构成。
”流程“ 由多个”对话动作“和对话动作之间的”跳转“构成。
平台抽象了最常用的”对话动作“,称为”对话单元“。
5.4.1意图的生效状态
意图有三种生效状态:
“已生效”状态:用户消息可以触发意图并进入意图对应的流程。通常, 希望机器人针对这个意图,与终端用户交互时,设置为“已生效”。
“未生效”状态:用户消息不能触发意图并进入意图对应的流程。通常,意图对应的流程仍在搭建中时,将意图设置为“未生效”。
“调试中”状态:用户消息可以触发意图并进入意图对应的流程。与此同时,流程执行过程中会展示详细的执行细节。
如何生效意图
当意图的触发器和其关联的流程都设置完成之后,你就可以让这个意图“生效”并体验效果了。
1 修改单一意图的“生效状态”
在意图列表中,点击意图的生效状态。
在下拉列表中,点击选择需要的状态。
2 批量修改所有意图的“生效状态”
点击意图列表上方的全部生效,即可将所有意图状态改为“已生效”。
点击意图列表上方的…,再选择全部失效,即可将所有意图状态改为“未生效”。
提示: 如果将意图设置为“未生效”,那么在调试机器人、体验机器人以及其他各个渠道,该意图都不会被触发。 但如果在一个意图中使用了“意图终点单元”来跳转到一个“未生效”的意图,那么这个“未生效”的意图可以被正常启动并执行。
5.4.2利用“无意图”防止“误触发”
无意图:系统默认生成,非必需。无意图是不应该触发意图的相似说法的集合,仅包含触发器,无流程。
有时候,开发者会面对这样的情况:非常相近的两句话,一句话需要触发意图;另一句不希望触发意图。
举个例子,有一个意图是“查询婴儿能不能吃某种食物”。
当用户问“婴儿能不能吃牛肉”时,希望触发这个意图;但是,当用户问“高血压能不能吃牛肉”时,不希望触发意图。
当机器人学习还不够充分时,会在用户说第二句话时也触发意图。这种情况我们称为“误触发”。
为了避免“误触发”,你可以使用“无意图”的功能。开发者可以直接将容易导致“误触发”的用户表达加入到“无意图”的触发器中。
任何触发了“无意图”的用户表达,都不会令机器人启动任何流程。所以,“无意图“不对应任何流程,也无需编辑流程。
在系统上,操作”无意图“的步骤为:
1 修改无意图的触发器。
点击无意图的设置触发器。
在其中填入不希望触发意图的关键词或相似说法,比如在上述例子中,可在相似问题中填入“高血压可不可以吃牛肉”。
点击保存。
2 修改无意图的“生效状态”
- 更改无意图的生效状态为“已生效”。
5.4.3利用“预处理意图”实现一些业务逻辑
预处理意图:预处理意图:系统默认生成,非必需。预处理意图用来设置主要流程开始前需完成的准备工作。
举个例子,不管用户的表达具体触发了哪个意图,你希望统计用户与机器人总共对话了多少轮次。这个数据对于分析机器人的效果很有帮助。
这种情况下就可以使用”预处理意图“的功能。预处理意图的特点是所有用户的表达在进入任务后都会触发”预处理意图“。因此,开发者不需要设置触发器,仅需要通过编辑与之对应的流程来实现一些业务逻辑。
在系统上,操作”预处理意图“的步骤为:
1 编辑“预处理意图”对应的流程。
2 在意图管理页面,更改预处理意图的生效状态为“已生效”。
注意:确有必要的情况下,我们才会使用预处理和无意图工人,简单的任务一般不会涉及预处理和无意图。
如果没有特殊指明,下文提及“意图”时,指的都是普遍意义的“意图”。
5.4.4意图流程中插入问答对话
有时候,当机器人向用户询问一个信息时,用户没有给出当前单元期待的信息、而是转换了话题。
比如下面这样的对话:
对话示例
机器人:请问你要去哪个城市?
用户:机票和火车票你都可以订吗?
在这种情况下,你可以让机器人尝试用知识点回复用户,然后再回到当前单元继续询问。平台提供“触发知识点”功能来实现这个效果。
触发知识点:在任务对话中运行到询问填槽单元时,如果用户消息中没有当前单元期待的信息,那么尝试去问答对话中匹配知识点。
如果匹配到问答的知识点,则先回复知识点的答案,然后当前单元重复询问。
如果没有匹配到问答的知识点,则当前单元直接重复询问。
注:假设此时还没有超出询问填槽单元的尝试询问次数。
在系统上,开启”意图流程中插入问答式对话“的步骤为:
1 点击意图设置。
2 将是否触发知识点设置为“是”。
5.5触发器
每一个“意图”都有“触发器”。之所以叫“触发”,是指机器人识别出用户意图后,要“触发”之后预先设定好的由多轮交互构成的一个“意图流程”。
“触发器”中存放的是开发者维护的一些意图触发条件。平台的底层算法将“学习”这些触发条件,教会机器人如何理解用户意图。
按照触发方式的不同,“触发器”中有三种类型的触发条件:
关键词。当用户消息中的信息片段严格匹配或整体包含“触发器”中维护的关键词时,意图被识别,这个意图所关联的流程被“触发”。关键词触发又包含“等于”和“包含”两种。
相似问题。当用户消息与“触发器”中的某个相似问题在语义上很接近时,意图被识别,这个意图所关联的流程被“触发”。
句式。当用户消息与“触发器”中的某个句式在语义上很接近时,意图被识别,这个意图所关联的流程被“触发”。
5.6意图与触发器的创建
进入对话搭建-任务对话-场景列表点击进入已创建的场景,后按以下步骤操作
1 新建意图
点击新建意图。
填写意图名称。
点击保存。
在意图创建完成后,如果需要修改名称,可点击意图名称的位置,进入编辑模式。
通常在这时,我们就会将意图设置为“已生效”或“调试中”,方便测试与调试。
2 对单独一个意图设置触发器
点击设置触发器。
在右侧滑出的触发器编辑器中,输入必要的关键词组或相似说法。
点击保存。
3 触发器导入与导出
点击导入触发器旁边的“...”。
点击批量导出触发器,就可以将触发器内容下载到本地。
点击导入触发器,可将本地的触发器文件上传到系统中。
系统中的触发器内容会根据文件内容自动更新。
利用“推荐句式”提升触发器的泛化能力
这个功能与知识点详情中的“推荐句式”使用方法一致。详情可参考[知识点配置]一章中的进阶指南-利用“推荐句式”在提升泛化能力的同时缩减相似问数量。
5.7意图的画布操作
意图流程是可视化搭建意图流程的工具。通过画布上对单元的拖拽和链接,就能实现业务对话的设计。
意图流程有三个部分:
菜单栏:在页面顶部。用于设置意图的整体设置、切换、发布和还原意图。
对话单元列表:在页面左侧。用于向画布中添加对话单元。
画布区域:除了菜单栏和对话单元列表之外的其他区域。用于编辑对话单元之间的连线、移动单元和连线的位置等。
5.7.1在画布上编辑和发布一个意图流程
编辑和发布一个意图流程包含以下步骤:
1 从对话单元列表中选择一个单元,点击或者拖拽它到画布中,就在意图流程中添加了这个单元。
添加对话单元的两种方式:
- 拖拽:将左侧对话单元列表中的一个单元拖拽到画布区域。
- 单击:单击左侧对话单元列表中的一个单元。
添加对话单元连线的两种方式:
- 在单元上操作:在画布中的单元上添加跳转关系,并拖拽连线。
- 在单元详情中操作:打开单元详情,设置跳转关系后,会在画布中形成相应的连线。
2 编辑对话单元的详情。详细操作请见相应的[对话单元]章节。
3 添加对话单元之间的连线(即,跳转关系)。详细操作请见相应的[对话单元]章节。
4 发布意图。
5 生效意图。回到意图管理页面,将这个意图的生效状态设置为“已生效”。
提示: 画布上的变更会实时保存为草稿。但只有当意图完成了发布之后,画布上的效果才能在机器人中体现出来。
快速定位画布位置:如果需要快速定位到画布上的位置,你可以拖拽缩略图中深色区域的位置来定位。
如果需要拓展画布的宽度,你可以:
- 将画布移动到最右侧,鼠标悬停在最右侧的位置,即可看到一个浅蓝色的拓展条。
- 点击拓展条,画布将向右拓展。
如果需要拓展画布的高度,你可以:
- 将画布移动到最底部,鼠标悬停在最底部的位置,即可看到一个浅蓝色的拓展条。
- 点击拓展条,画布将向下拓展。
5.7.2画布菜单栏
切换意图:你可以点击意图名称,在下拉列表中切换到另一个意图。
还原:如果画布中的内容已经做了调整,但希望退回到上一次发布时的样子,你可以点击「还原」按钮,将草稿恢复到最近一次发布的版本。
高级选项:你还可以打开「高级选项」,变更保留词槽的开关。
- 保留词槽开启时:当意图执行到一个流程分支的最后一个单元时,词槽值将保留。在意图的闲置等待时长内,用户发消息时会继续执行该意图;
- 保留词槽关闭时,如果关闭,词槽值将清空。在意图的闲置等待时长内,用户发消息时意图流程会从头开始。
提示: 意图终点单元的“在当前单元保留词槽”的优先级高于此处设置。
5.8对话单元
对话单元是意图流程中的各个节点。在对话单元中,你可以规定机器人每一步的动作,包括机器人与用户的一次对话互动、调用一次第三方接口、查询一次表格数据等。
不同的对话单元之间按照单元中设置的跳转关系被连接起来。
比如: 在“订车票”的意图中,机器人需要分别询问用户出发城市、到达城市、出发日期、出发时间,然后查询车次,再询问用户最终选择的车次。
那么,需要在意图流程中添加以下5个询问填槽单元:
- 询问出发城市
- 询问到达城市
- 询问出发日期
- 询问出发时间
- 询问选择哪个车次
以及1个单槽接口单元:
- 查询车次
单元的类型
平台中提供了多种对话单元类型,每一种类型可以完成不同的对话动作。
- [询问填槽单元]:询问用户,并根据用户回复来填充词槽。如果单元的关联词槽在之前的用户回复中已经被填充,则不会询问。
- [消息发送单元]:发送一组消息给用户。
- [单槽接口单元]:从开发者接口中获取返回值填入关联词槽,并根据词槽值进行分支跳转。
- [多槽接口单元]:从开发者接口中获取多个返回值填入多个词槽。
- [静默填槽单元]:持续监听用户在当前意图流程中发来的消息。如果获取到能填充到关联词槽的信息,则填槽,并根据词槽值在当前单元进行分支跳转。如果没有获取,不主动询问用户。
- [词槽运算单元]:对词槽进行运算。运算方式包括:重置词槽、将文本或其他词槽的值赋值给词槽、给词槽中的值做加减乘除运算。
- [词槽记录单元]:每次经过这个单元,就会将关联词槽中的值保存为一条记录。该记录可在数据分析的用户反馈关于[任务信息收集]页面查看。
- [表格读取单元]:根据指定条件去表格中查找相应内容并存入关联词槽。
- [表格写入单元]:根据指定条件将关联词槽中的值写入到表格中。
- [属性读取单元]:读取用户属性填入词槽,并根据词槽值进行分支跳转。
- [属性写入单元]:将词槽值写入用户属性。
- [意图终点单元]:表示当前意图完成。在完成的同时,可以选择跳转到指定意图或跳转到上一个意图。
5.8.1询问填槽单元
机器人经常需要通过“询问”用户,并从用户回复的话中获取完成任务的必要信息。
比如,为了完成“订机票”这一任务意图,机器人会向用户询问“你要去哪里“、”你从哪里出发“、”你什么时候出发“。通过用户回答“从北京到上海,10点出发”这样的信息,机器人获取信息,推进对话。
这样的对话交互可以通过使用询问填槽单元来实现。
下文将介绍这些内容:
- 询问填槽单元相关的重要概念
- 询问填槽单元的基本操作
- 使用询问填槽单元处理异常情况的进阶指南
5.8.1.1词槽的“关联”
在任务型对话中,大多数单元都需要“关联”(或者“绑定”)词槽。每当意图流程运行到一个单元,机器人执行单元中设定的操作、获取信息、并赋值给关联词槽。
在询问填槽单元中,开发者需要指定一个关联词槽来存放“从用户回复中”抽取的核心信息。
5.8.1.2单元的“跳转关系”
一个多轮对话流程的是由“单元”和“单元之间的跳转关系”来构成的。在每一个单元的跳转关系中,你可以设置在不同情况下,这个单元执行完成后应该执行哪个单元。平台上的所有单元都需要指定其“跳转关系”,以便决定机器人的下一步动作。
在意图流程的画布中,跳转关系表现为单元之间的连线。比如下图所示的两个询问填槽单元之间,由于前一个单元跳转到了后一个单元,于是形成了单元连线:
通常,“跳转关系”是由词槽中被填充的值来决定的。不同的赋值会改变对话的走向。
在询问填槽单元中,有以下几种跳转关系:
分支跳转:指定一个规则,当词槽值符合该规则时,就跳转到这一个分支跳转所指定的进入单元中。 分支跳转提供以下的规则逻辑符:
- 词槽值的比较:等于、不等于、大于、大于等于、小于、小于等于。
- 词槽值是否属于实体:属于实体、不属于实体。
- 词槽值是否符合正则表达式:符合正则、不符合正则。
默认跳转:当词槽不符合任意一个分支跳转中所规定的规则时,就跳转到默认跳转所指定的进入单元中。
提示 如果词槽的值满足多个分支跳转条件,机器人会选择排在最上面的分支跳转条件来执行跳转。
在画布上,添加一个“询问填槽单元”,需要:
1 点击左侧对话单元菜单中的询问填槽单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称。
4 选择关联词槽。
- 如果希望关联的词槽还未创建,可以点击新建词槽去创建。
- 也可以到词槽管理页面创建。
5 选择一种消息格式(文本、图片等),输入询问语句内容。
- 消息格式是询问语句的不同格式。在这里可查看系统中支持的消息类型。
6 如果需要,可以添加更多的询问语句。
机器人会将每一条询问语句作为一个消息发送。
一个单元中最多可添加10条询问语句。
7 设置跳转关系。
8 点击单元详情右上角的保存。
这样就完成了一个单元的基本设置。
5.8.1.3询问策略
尽管我们希望由机器人主导用户、通过多个“一问一答”的交互顺利完成任务,但现实中的情况往往很复杂。
为了处理各种导致对话偏离目标的异常情况,你可以使用“询问策略”,让对话回归主线。
这一部分内容将在“进阶指南”中展开讲述。
默认值-用户任务对话中“答非所问”
用户有可能不会按照设定的方式,回答机器人的问题。例如,
对话示例
机器人:你的出发城市是哪里?
用户:我要定机票。
为了在上述对话情形中推进对话,可以采用多次询问、并配置默认值的对话策略。
在该策略下,机器人的处理方式是:
- 如果机器人在第一次询问后没有得到答案,那么,机器人会询问多次。
- 如果达到询问次数的上线,机器人依然没有获得可填槽的合法值,那么,将用默认值来填槽。
在该策略下的一个对话示例:
对话示例
机器人:你的出发城市是哪里?
用户:我要定机票。
机器人:你的出发城市是哪里?
用户:不知道。
机器人:好的,为你设置了出发城市“北京”,请问你的到达城市是哪里?
可以看到,在上述对话示例中机器人询问了两次,最终,用兜底值“北京”填槽并推动对话进入下一个单元“询问达到城市”。
1 在“询问填槽单元”的“询问填槽”部分,切换到“对话策略”中
2 设置尝试询问次数,控制机器人的询问次数。
3 在“询问次数用尽时,使用以下值填槽并作为跳转依据”中,填入默认值。
重复询问——增加提问的多样性
有时候你可能希望当用户答非所问时,机器人能够更人性化地换一种方式提问。
为了在上述对话情形中推进对话,平台建议你采取“依次回复一条”的对话策略。
在该策略下,机器人会:
- 在多个询问话术中,每次询问都按照顺序,选择一条话术回复。
在该策略下,一个对话示例:
对话示例
机器人:你的出发城市是哪里?
用户:我要定机票。
机器人:请问方便告知你的出发城市吗?
话术策略可以这样配置:
1 在询问语句中,选择依次回复一条。
2 点击文本图标,增加一个文本编辑区域。
3 在文本编辑区域中,输入另一种询问话术。
4 点击保存。
追问——提高转化效率
在对话过程中,用户可能因为忙碌暂时停止了交互。机器人此时无法向后执行流程。例如,
对话示例
机器人:你的出发城市是哪里?
用户:(静默中)
为了在上述对话情形中推进对话,平台建议你采取“追问”的对话策略。
在该策略下,一个对话示例:
对话示例
机器人:你的出发城市是哪里?
用户:(静默中)
机器人:很抱歉再次打扰您,请问,您要从哪里出发呢?
追问参考以下配置:
1 在“询问填槽单元”的“询问填槽”部分,切换到“对话策略”中
2 开启用户不说话时追问,
3 配置“追问”话术和“等待时间”
提示 用户不说话时追问的等待时长,不能超出意图和场景的闲置等待时长。关于闲置等待时长的描述,详见[意图管理]。
澄清——处理用户回答了太多信息
有时用户可能提供了多个可以被填入词槽的值,机器人无法判断哪一个应该用于填槽。
举个例子,在下图所示的场景中,根据用户预定会议室的语句,机器人查询到了多个会议室:
对话示例
用户:帮我预定明天10点的会议室
(机器人查询到了三个会议室明天10点有空闲)
为了在上述对话情形中推进对话,平台建议你采取“澄清”的对话策略。此时,机器人会以快捷回复的方式列出多个值的内容,供用户选择。以用户选择的值填槽。
在该策略下,一个对话示例:
对话示例
用户:帮我预定明天10点的会议室
机器人:你说的是下面哪一个? 会议室A 会议室B 会议室C
澄清的配置:
1 在“询问填槽单元”的“询问填槽”部分,切换到“对话策略”中
2 开启机器人得到多个值时,向用户澄清
提示: 澄清功能关闭时,机器人得到的多个值会拼接成字符串,整体填入关联词槽。
引用词槽——让用户感受到个性化的服务
有时候你可能希望机器人在与用户对话时能够使用之前收集到的信息。
比如,在第一个询问填槽单元询问了出发城市之后,希望在第二个询问填槽单元中说出这个城市,表明机器人接收到了信息。
如果想要实现上述效果,你可以采取“引用词槽”的方式,得到如下的对话效果:
对话示例
机器人:你的出发城市是哪里?
用户:北京
机器人:好的, 你要从北京去哪里呢?
引用词槽从而展示信息可以这样操作:
1 在询问语句编辑区域的左下方,点击{}图标。
2 在弹窗中选择要插入的词槽。引用词槽后,会在询问语句中自动插入{slot=词槽名称}的语句片段。效果如下:
仅当前填槽——处理用户更改信息
在一些对话中,用户可能会希望更改自己告知过机器人的关键信息信息。
比如:
对话示例
机器人:请问,你要预定什么机票?
用户:从北京到上海的头等舱,帮我查一下。
机器人:有10个航班可以选择。详情如下:……
用户:不。不要头等舱了。看经济舱。
如果你希望允许用户更改关键信息,并使用新的信息去执行后续流程,你可以采取系统默认的“全局填槽”对话策略。
在该策略下,即使不在机器人询问关键信息的时候,用户更改了该关键信息,依然可以更新词槽。
在该策略下的一个对话示例:
对话示例
机器人:请问,你要预定什么机票?
用户:从北京到上海的,南航的飞机,帮我查一下。
机器人:有10个南航的航班,可以选择。详情如下:……
用户:不。我要看东航的。
机器人:有5个东航航班可以选择。详情如下:……
1 在“询问填槽单元”的“询问填槽”部分,切换到“对话策略”中
2 将仅在当前单元询问时填槽设置为关闭。
提示 如果该开关打开,表示只有当机器人询问时才填充这个词槽。如果机器人没有提问,即便用户主动回答也不会被识别。
询问中使用第三方数据来推进对话
有时候你可能希望机器人在与用户对话时,访问第三方的数据库、获得某些数据来推进对话。
为了在上述对话情形中推进对话,平台建议你使用“数据源 URL”的功能来实现该效果。
在该策略下的一个对话示例:
对话示例
机器人:请问,你要预定什么机票?
用户:从北京到上海的,南航的飞机,帮我查一下。
机器人:有10个南航的航班,可以选择。详情如下:……
此时,机器人会根据用户的出发地、目的地、航空公司信息,查询第三方的数据库,获得可选的航班列表。利用该数据,推进对话。
1 在高级设置的数据源URL中,填入第三方接口的请求语句。比如:
http://yourhttpserver:port?attr1_name={出发城市}&attr2_name={到达城市}
2 按照接口定义的返回格式来返回词槽值。
接口定义
接口请求格式
在发送请求时,询问填槽单元的数据源URL可以根据第三方接口的需要,拼接多个词槽值发送出去。
接口请求示例如下:
http://yourhttpserver:port?attr1_name={slot1_name}&attr2_name={_slot2_name}
其中,词槽名称有两种语法:
- 使用{slot1_name}时,如果该值属于某个实体,会替换成实体归一化的值。
- 使用{_slot2_name}会直接使用slot2的文本值。
比如,用户在2019年1月1日跟机器人说:“我要预定今天的会议室。”词槽“会议日期”获取到词槽值“今天”,并查询到“今天”属于实体“日期”。
如果用
http://yourhttpserver:port?attr_name={会议日期}
那么,attr_name=“2019-01-01”。
如果用
http://yourhttpserver:port?attr_name={_会议日期}
那么,attr_name=“今天”。
接口返回格式
在接收返回值时,询问填槽单元可以从第三方接口接收词槽值、以及待发送给用户的回复。其中:
- 接收词槽的值:通常需要返回。如果不返回,则词槽值为空,在判断跳转逻辑时会进入默认跳转。
- 发送给用户的回复:只支持文本。
接口返回示例如下:
{
"slot_values": ["slot value 1", "slot value 2", "...", "slot value N"],
"responses": [{
"content": "{
\"content\": \"文本消息内容\"}",
"type": "text"
}]
}
预置回复——“优雅”地限制用户选择
有时候,由于用户不熟悉机器人的提问,可能给出机器人预期之外的回复,导致机器人无法识别用户表达中的关键信息。
比如:
对话示例
机器人:请问,你要预定什么舱型?
用户:我要最好的。
此时,你可以利用可视化(GUI,Graphical User Interfers)组件来推动对话。系统中提供了“预置回复按钮”的功能来实现这个策略。
预置回复按钮提供给用户的选择,以便用户了解当前单元所预期得到的回答。
比如:
对话示例
机器人:请问,你要预定什么舱型?头等舱,商务舱,经济舱。
在网页中的效果如下:
1 在预置回复按钮中,点击一个按钮,输入提示内容。比如“头等舱”。
2 根据需要添加更多的按钮。
3 点击保存。
5.8.2消息发送单元
在多轮对话中,经常需要机器人向用户发送一句通知,但不预期用户作出回应。
- 比如:在订机票的意图的结尾,机器人发送,“感谢您使用服务,祝您旅途愉快!”
这样的对话交互可以通过使用消息发送单元来实现。
消息发送单元的基本操作:
1 点击左侧对话单元菜单中的消息发送单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称。
4 选择一种消息格式(文本、图片等),输入消息语句内容。
5 如果需要,可以添加更多的消息语句。机器人会将每一条询问语句作为一个消息发送。一个单元中最多可添加10条询问语句。
6 设置跳转关系。
7 点击单元详情右上角的保存。这样就完成了一个单元的基本设置。
在消息语句中推荐知识点
有时候你可能希望机器人在多轮对话的某个环节中,提示用户去了解更多信息。这些信息已经以知识点的形式存在于知识库中了,你希望机器人可以推荐给用户。
比如,机器人在意图末尾询问用户建议,同时,告诉用户还可以从机器人处了解什么。可以采用“推荐知识点”的对话策略。
在该策略下,一个对话示例:
对话示例
机器人:如果您是否对刚才的流程有任何建议,请留言。我还可以为您提供以下常见问题的解答: $\color{blue}{公司介绍}$ $\color{blue}{近期活动}$
在网页中的效果示例:
1 在消息语句编辑区域的右下方,点击关联图标。
2 在弹窗内输入关键词,搜索要推荐的知识点。
- 这里我们假设在知识库中已经有你需要推荐的知识点了。比如,在下面的例子中,已经创建好了“公司简介”和“报名其他活动”两个知识点:
3 点击要选择的知识点,即可将它加入到消息语句的下方。效果如下:
4 点击保存。
5.8.3单槽接口单元
有时候在意图流程中,机器人需要从第三方接口获取信息,并在后续的流程中使用这个信息。
- 比如,在查询机票的意图中有以下步骤:
- 机器人询问用户出发地、到达地、出发时间。
- 机器人将出发地、到达地、出发时间传入第三方接口,接口根据这三个信息返回航班信息。
- 机器人将查询到的航班号发送给用户。
这样的对话交互可以通过使用单槽接口单元来实现。
单元中接收词槽是当前单元希望存放收集信息的变量。
对于单槽接口单元来说,接收词槽是机器人从第三方接口获得的信息。
- 比如,在查询机票的例子中,接收词槽可选择“航班信息”。
1 点击左侧对话单元菜单中的单槽接口单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称。
4 选择接收词槽。
- 如果希望选择的词槽还未创建,可以点击新建词槽去创建。也可以到词槽管理页面创建。
5 在接口URL中输入第三方接口的地址。接口的请求和返回格式参见接口定义。
6 设置跳转关系。
7 点击单元详情右上角的保存。这样就完成了一个单元的基本设置。
接口定义
接口请求格式
在发送请求时,单槽接口单元可以根据第三方接口的需要,拼接多个词槽值发送出去。
接口请求格式如下:
http://yourhttpserver:port?attr1_name={slot1_name}&attr2_name={_slot2_name}
其中,词槽名称有两种语法:
- 使用{slot1_name}时,如果该值属于某个实体,会替换成实体归一化的值。
- 使用{_slot2_name}会直接使用slot2的文本值。
比如,用户在2019年1月1日跟机器人说:“我要预定今天的会议室。”词槽“会议日期”获取到词槽值“今天”,并查询到“今天”属于实体“日期”。
如果用
http://yourhttpserver:port?attr_name={会议日期}
那么,attr_name=“2019-01-01”。
如果用
http://yourhttpserver:port?attr_name={_会议日期}
那么,attr_name=“今天”。
接口返回格式
在接收返回值时,单槽接口单元可以从第三方接口接收词槽值、以及待发送给用户的回复。其中:
- 接收词槽的值:通常需要返回。如果不返回,则词槽值为空,在判断跳转逻辑时会进入默认跳转。
- 发送给用户的回复:可选。支持不同消息格式。
接口返回参数如下:
{
"slot_values": ["slot value 1", "slot value 2", "...", "slot value N"],
"msg_body": [{
"data":{
"content": "测试文本消息"
},
"type":"text"
},
{
"data":{
"resource_url": "http://图片地址"
},
"type": "image"
},
{
"data":{
"resource_url": "http://音频地址",
"type": "0",
"recognition": "语音识别的文字内容"
},
"type": "voice"
},
{
"data":{
"title":"视频名称",
"thumb":"http://视频缩略图地址",
"description":"视频描述",
"resource_url": "http://视频地址"
},
"type": "video"
},
{
"data":{
"title":"卡片名称",
"description":"卡片描述",
"cover_url": "http://卡片封面地址",
"destination_url": "https://卡片链接地址"
},
"type": "share_link"
},
{
"data":{
"filename":"文档名称",
"resource_url": "http://文件地址"
},
"type": "file"
},
{
"data":{
"resource_url": "https://图文链接地址"
},
"type": "rich_text"
}]
}
利用接口模拟值来调试意图流程
如果在当前单元需要调用的接口还尚未搭建,你可以设置接口模拟值,填入词槽中,以便后续流程可以顺利进行。
1 开启启用模拟填槽。
2 输入一个值。每次意图流程运行到这个单元时,这个值就会被填入当前单元的词槽中。
5.8.4多槽接口单元
有时候在意图流程中,机器人需要从第三方接口获取多个信息,并在后续的流程中使用这些信息。
- 比如,在查询机票的意图中有以下步骤:
- 机器人询问用户出发地、到达地、出发时间。
- 机器人将出发地、到达地、出发时间传入第三方接口,接口根据这三个信息返回航班信息。
- 机器人将查询到的航班信息发送给用户。
机器人查询到的航班信息很可能包含了多个字段,比如,航班号、机票总额、转机信息等。
如果使用[单槽接口单元],需要将以上3个字段拼接后赋值给接收词槽“航班信息”。 在经过这个单元后,效果为:
词槽“航班信息”:航班号:SA1234;机票总额: ¥3000;转机信息: 直飞。
但期望的理想效果可能是:
词槽“航班号”:SA1234; 词槽“机票总额”: ¥3000; 词槽“转机信息”: 直飞。
这时,你就可以通过使用多槽接口单元来实现。多槽接口单元与单槽接口单元的区别是它可以在一个单元内、通过一次对第三方接口的调用、获得多个词槽值。
1 点击左侧对话单元菜单中的多槽接口单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称。
4 在接口URL中输入第三方接口的地址。接口的请求和返回格式参见接口定义。
5 设置跳转关系。
6 点击单元详情右上角的保存。这样就完成了一个单元的基本设置。
接口定义
接口请求格式
在发送请求时,多槽接口单元可以根据第三方接口的需要,拼接多个词槽值发送出去。
接口请求格式如下:
http://yourhttpserver:port?attr1_name={slot1_name}&attr2_name={_slot2_name}
其中,词槽名称有两种语法:
- 使用{slot1_name}时,如果该值属于某个实体,会替换成实体归一化的值。
- 使用{_slot2_name}会直接使用slot2的文本值。
比如,用户在2019年1月1日跟机器人说:“我要预定今天的会议室。”词槽“会议日期”获取到词槽值“今天”,并查询到“今天”属于实体“日期”。
如果用:
http://yourhttpserver:port?attr_name={会议日期}
那么,attr_name=“2019-01-01”。
如果用:
http://yourhttpserver:port?attr_name={_会议日期}
那么,attr_name=“今天”。
接口返回格式
在接收返回值时,多槽接口单元可以从第三方接口接收多个词槽的词槽值、以及待发送给用户的回复。其中:
- 接收词槽的值:通常需要返回。如果不返回,则词槽值为空,在判断跳转逻辑时会进入默认跳转。
- 发送给用户的回复:可选。支持不同消息格式。
接口返回参数如下:
{
"slots": [{
"name":"new_slot_name",
"value":"new_slot_value"
},{
"name":"new_slot_name",
"value":"new_slot_value"
}
],
"msg_body": [{
"data":{
"content": "测试文本消息"
},
"type":"text"
},
{
"data":{
"resource_url": "http://图片地址"
},
"type": "image"
},
{
"data":{
"resource_url": "http://音频地址",
"type": "0",
"recognition": "语音识别的文字内容"
},
"type": "voice"
},
{
"data":{
"title":"视频名称",
"thumb":"http://视频缩略图地址",
"description":"视频描述",
"resource_url": "http://视频地址"
},
"type": "video"
},
{
"data":{
"title":"卡片名称",
"description":"卡片描述",
"cover_url": "http://卡片封面地址",
"destination_url": "https://卡片链接地址"
},
"type": "share_link"
},
{
"data":{
"filename":"文档名称",
"resource_url": "http://文件地址"
},
"type": "file"
},
{
"data":{
"resource_url": "https://图文链接地址"
},
"type": "rich_text"
}]
}
利用接口模拟值来调试意图流程
如果在当前单元需要调用的接口还尚未搭建,你可以设置接口模拟值,填入词槽中,以便后续流程可以顺利进行。
1 开启启用模拟填槽。
2 输入一个值。每次意图流程运行到这个单元时,这个值就会被填入当前单元的词槽中。
5.8.5静默填槽单元
通常,对话有一个主流程,即在开发者的预期中、机器人和用户交互的主要路径。然而,除了主流程,很多对话还需要一些分支流程来处理一些对话的异常情况。
比如,用户与机器人通过对话来订票。订票的主流程中,机器人会询问用户出发城市、到达城市、出发日期等信息。但是,用户有可能需要修改已经提供的信息,表达“我想要重新查询”,“更换出发城市”这样的意愿。这个时候,机器人需要回答之前流程的某个节点。
这样的对话交互可以通过使用静默填槽单元来实现。
隐藏分支
与主流程相对的,隐藏分支是独立于主流程的备选分支。一般情况下该分支不被激活,保证用户沿着主流程完成对话。特殊情况下,激活该分支来处理一些事务。
隐藏分支激活的机制是:
1 为静默填槽单元绑定一个词槽。在对话过程中,机器人不会主动要求用户填槽,而是“被动地”接受。
2 当用户的表达中包含了静默填槽单元所被动等待的信息(即,词槽所引用的实体)时,机器人会填充静默填槽单元的关联词槽。
3 此时,静默填槽单元被激活,开始执行,并根据此时词槽中的值和跳转关系向后执行流程。这样就达到了改变流程走向的目的。
以上文提到的订票意图为例,我们来增加一个静默填槽单元,用于处理用户“重新查询”的请求。要实现这个机制,需要分三个步骤:
创建一个枚举实体,存放用户表达“重新查询”请求时可能用到的表达方式。关于实体的操作指南详见[实体]。 创建后的效果如下:
创建一个词槽,关联上一步创建的枚举实体。关于词槽的操作指南详见[词槽]。 创建后的效果如下:
添加静默填槽单元,关联上一步创建的词槽。效果如下。
在静默填槽单元中的具体操作是:
1 点击左侧对话单元菜单中的静默填槽单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称。
4 选择关联词槽。
- 如果希望关联的词槽还未创建,可以点击新建词槽去创建。也可以到词槽管理页面创建。
5 设置跳转关系。
对于静默填槽单元,有以下几种跳转关系:
- 分支跳转:指定一个规则,当词槽值符合该规则时,就跳转到这一个分支跳转所指定的进入单元中。
分支跳转提供以下的规则逻辑符:
- 词槽值的比较:等于、不等于、大于、大于等于、小于、小于等于。
- 词槽值是否属于实体:属于实体、不属于实体。
- 词槽值是否符合正则表达式:符合正则、不符合正则。
- 默认跳转:
- 当词槽中的值不符合分支跳转条件,那么进入单元:不符合任意一个分支跳转中所规定的规则时,就跳转到的此处选择的单元中。
- 当没有获取到词槽值时,那么跳转到:词槽值没有获取到时,跳转到此处选择的单元中。
提示 如果词槽的值满足多个分支跳转条件,机器人会选择排在最上面的分支跳转条件来执行跳转。
6 点击单元详情右上角的保存。这样就完成了一个单元的基本设置。
5.8.6词槽运算单元
很多时候,机器人从终端用户获取的信息并不是收集任务最终需要的数据,而需要进行加工。但如果只使用[询问填槽单元]的话,词槽中的数据是不能改变的。
例如,词槽中获得的数据需要进行如下更改:
- 无论这个词槽之前填入了什么值,只要用户流程走到这个单元,就需要将词槽里的值重置为一个定值。
- 用户输入的信息分别存在两个词槽中,但是需要将另一个词槽的内容拼接到当前词槽。
- 需要对用户填入的数据进行数学四则运算。
- 对词槽中的关键信息进行提取替换,赋值给另一个词槽。
以上这三种需求,可以使用词槽运算单元来实现。
清空模式 当词槽运算单元设为清空模式,关联词槽将被清空。 赋值模式 当词槽运算单元设为赋值模式,关联词槽内的数据可以被赋值为:
- 文本
- 其它词槽值
- 以上两种值的拼接结果
在赋值模式单元引用其他词槽值为关联词槽赋值时,预设格式为{slot=词槽名}。
例如:
拼接模式中设置了表达式“{slot=月份}月{slot=日期}日”;
并且“月份”词槽中填入数字1,“日期”词槽中填入数据24;
那么当流程经过这个单元时,会将文本“1月24日”填入关联词槽。
计算模式 当词槽运算单元设为计算模式,可以直接将“关联词槽内的数据”与“类似拼接模式一样拼接后的数据”进行四则运算。
值得注意的是:词槽内的数据都以文本格式存储,在后台会将文本转换成数字进行计算,因此如果“词槽内的数据”和“拼接后的数据”不能转换为数字的话,该单元无法生效。
例如:
关联词槽内数据为“10”,选择运算符“+”;
拼接数据表达式为{slot=“整数”}.{slot=“小数”};
并且“整数”词槽中填入数字1,“小数”词槽中填入数据24;
那么当流程经过这个单元时,
会计算10+1.24,并将11.24填入关联词槽。
正则替换模式 正则替换模式,能够实现从词槽中抽取一个局部,填入另一个词槽。如下是从一个收集到身份证号的词槽抽取出出生年月日,拼接并填入了另一个出生日期词槽。
操作说明
1 点击编辑图标,可以开始配置详情。
2 填入单元名称,一般是单元所实现的作用。
3 设置模式。
清空模式:清空关联词槽中的值。
赋值模式:在任务流程中,有时需要给某个词槽赋其他词槽的值。这时可以选择赋值模式。
输入一段文本作为关联词槽的值。
在文本中插入词槽,文本和词槽的值会拼接在一起作为关联词槽的值,例如,设置运算单元的赋值模式为:“{slot=月份}月{slot=日}日”。
当任务进行到该运算单元时,假设:“月份”词槽中的值为“6”,“日期”词槽中的值为“5”,那么,关联词槽中会填入拼接后的文本,也就是:6月5日。
计算模式:给词槽值加减乘除一个特定值。
这个特定值可以是数字。
也可以引用某个词槽。点击文本框右侧“{}”图标就可以插入词槽。
- test的值是3,就给他加上1,让test的值变成4。
正则替换模式:能够实现从词槽中抽取一个局部,填入另一个词槽。
- 如下是从一个收集到身份证号的词槽抽取出出生年月日,拼接并填入了另一个出生日期词槽。
4 选择要关联到这个单元的词槽,词槽内的数据将会按照单元预设的运算模式被修改。
5 跳转关系:为这个单元配置跳转链接,跳转链接可以基于词槽里的值进行判断跳转。机器人执行修改词槽后,就会跳转到配置的单元。
6 点击单元详情右上角的保存。
这样就完成了一个单元的基本设置。
5.8.7词槽记录单元
很多时候,机器人从词槽中收集到了的数据。这些数据信息需要被汇总为一条记录,保存成一个包含各个词槽等信息的汇总表格。
比如举办一个活动的报名流程中,需要提前收集参加活动的人员情况,例如姓名、年龄、手机号等信息。但使用[询问填槽单元]的话,只能在对话中暂时获得各个词槽的信息,不能将数据长期保留下来。
本平台提供了词槽记录单元,来实现自定义需要收集的词槽数据的功能。
下文将介绍词槽记录单元的基本操作:
在画布上,添加一个词槽记录单元,需要:
1 点击左侧对话单元菜单中的词槽记录单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称,一般是单元所实现的作用。
4 添加词槽记录单元后,在要记录的词槽中点击选择词槽,可以配置要保存下来的信息(词槽)。
5 设置跳转关系。可以为这个单元配置跳转链接,跳转链接可以基于词槽里的值进行判断跳转。机器人执行修改词槽后,就会跳转到配置的单元。
6 点击单元详情右上角的保存。
这样就完成了一个单元的基本设置。
7 查看收集到的信息。
机器人在线上运行中,如果收集到了信息,可以在[任务信息收集]页面查看。
提示: 体验版网页等正式渠道收集到的信息可以被展示在“信息收集”中。调试机器人是假用户假渠道,没有属性和记录。
5.8.8表格读取单元
延续表格知识图谱章节的示例,机器人和用户之间可能会发生如下一段对话:
对话示例
用户:沪深300是什么类型的基金?
机器人:沪深300是投资基金。
用户:好的,那购买方式为认购的基金有哪些?
机器人:交银、中海。
如果你已经构建了一个表格知识图谱。此时,为了实现上述效果,你可以利用表格读取单元,对表格数据进行查询,在多轮对话中完成对用户问题的回答。
用户问题自身可以看作是对表格数据的查询条件。常见的有两类查询条件:
已知“主体”和“属性”,查询“属性值”。
“沪深300是什么类型的基金?”
“基金最大的年化收益是多少?”
“沪深300和中海,谁的收益率更高?”
“沪深300比中海,收益率高多少?”
已知“属性”和“属性值”,查询“主体”。
“股票型基金有哪些?”
“股票型基金有几个?”
“股票型基金有没有沪深300?”
平台会将这个查询条件,转换成对二维表格的查询。这个查询的过程是通过“定位”来实现的。
“所在行”和“所在列”
为了回复上述查询,需要对表格知识图谱进行“定位”。
就像要确定一个二维平面上的任意一个点,需要X和Y两个坐标一样,要锁定表格知识图谱中的任何一个值,必须要确定“所在行”和“所在列”两个信息。
确定“所在行”,机器人需要做两件事:
第一件事:确定以哪一列的数据来判断查询结果的“所在行”。
第二件事:确定以这一列的哪个数据来锁定查询结果的“所在行”。
延续上文,为了回复“沪深300是什么类型的基金?”,机器人需要:1、以“基金”这一主体列的数据来判断查询结果的“所在行”;2、以“基金”这一列的“沪深300”来锁定查询结果的“所在行”。
确定“所在列”,机器人需要做一件事:
确定以哪一列的数据来判断查询结果的“所在列”。
延续上文,为了回复“沪深300是什么类型的基金?”,机器人需要:1、将“类型”这一属性列作为数据“所在列”。
“定位” 四要素:定位列、定位值、返回列、返回值
在平台上,为了确定“所在行”和“所在列”,需要在平台上指定“定位列”、“定位值”、“返回列”、“返回值”。
定位列:指定这一列,帮助机器人完成确定“所在行”的第一件事。
定位值:指定这一值,帮助机器人完成确定“所在行”的第二件事。
返回列:指定这一列,帮助机器人完成确定“所在列”的第三件事。
返回值:查询结果。
得到查询结果之后,开发者可以将结果包装成一个答案,回复给用户。
配置读表单元
在了解了上述概念后,通过如下步骤配置一个读表单元:
1 在读表单元详情中,选择表格下拉菜单中选择要进行查询的表格。
- 需要先创建表格知识图谱,再在读表单元中选择表格。
2 在定位列下拉菜单中,选择一个列名,表头中为该列名的列,将作为查表的定位列。
3 输入定位值,该定位值作为确定数据“所在行”的依据。
4 在返回列下拉菜单中,选择一个列名,表头中为该列名的列,将作为查表的返回列。
5 在返回值中,配置词槽,用于保存查询结果;
6 配置“跳转关系”。
查询成功:成功查到了结果,这时链接消息单元回复查询结果;
查询失败:查询失败了,可能是表格中没有这个信息,这时链接消息单元告知用户没有查到结果。
如上,一个简单的读表单元,就配置完成了。
利用词槽动态地配置“定位列”、“定位值”、“返回列”
在确定“定位列”、“定位值”、“返回列”的时候,都可以通过配置一个词槽,利用词槽获取的值,动态地指定这三个参数的值。
情形一: 动态配置“定位值”
如果开发者希望用户能够查询基金表格知识图谱中的任何一个主体的“类型”。这样一来,定位行是什么就取决于用户要查什么。
此时,定位值是动态的,用户说什么基金,定位值就是什么基金。在平台配置完成后,可以实现这样的效果:
对话示例
用户:沪深300是什么类型的基金?
机器人:沪深300是投资基金。
用户:那交银呢?
机器人:交银也是投资基金。
情形二: 动态配置“定位列”
如果开发者希望用户能够查询基金表格知识图谱中的满足某种属性的主体的其他属性值。这样一来,定位列是什么就取决于用户要查什么。
此时,定位列是动态的,用户说什么属性,定位列就是什么属性。在平台配置完成后,可以实现这样的效果:
对话示例
用户:类型为指数型的基金,年涨幅是多少?
机器人:符合条件的基金是中海,它的年涨幅是0.34。
情形三: 动态配置“返回列”
如果开发者希望用户能够查询基金表格知识图谱中的任意某种属性的属性值。这样一来,返回列是什么就取决于用户要查什么。
此时,返回列是动态的,用户说什么属性,返回列就是什么属性。在平台配置完成后,可以实现这样的效果:
对话示例
用户:沪深300是什么类型的基金?
机器人:沪深300是投资基金。
用户:那年涨幅是多少?
机器人:年涨幅是0.34。
以上述情形一为例,在平台上可进行如下设置:
1 给“基金”这一列关联一个“基金”的枚举实体,确保用户说的任何基金名称,都能被抽取出来。
2 指定一个词槽“查询基金”,这个词槽用于保存从用户表达中抽取到的基金名称。
3 在配置读表单元时,在输入定位值的时候,通过输入这个词槽(语法为:{slot = 查询基金}),来表示定位值为词槽中的值。
表格查询条件扩展
平台默认的查询条件是“=”,即定位值完全等于表格中的值时,才能定位行。
平台总共可以支持四种查询条件,具体如下:
当对应列的数据格式设置为“文本”时,支持的查询条件为“=”、“包含”,比如:查询主演为“沈腾”的电影有哪些,查询演员中包含“沈腾”的电影有哪些等。
当对应列的数据格式设置为“整数”、“小数”、“日期”时,支持的查询条件为“=”、“<”、“>”,比如:查询2020-01-01之后的车票预订情况,查询年化收益>0.1的基金等。
平台默认的查询条件是“=”,即定位值完全等于表格中的值时,才能定位行。
平台总共可以支持四种查询条件,具体如下:
1 创建表头时,指定表头某列的数据格式。
2 在读表单元定位列时,指定对“定位值”的“查询条件”。
5.8.9表格写入单元
在任务对话的多轮交互中,你可能需要将用户与机器人对话中的信息收集起来,放到一个表格中。
比如这些场景:
- 新员工入职,收集员工的个人信息。
- 会议室预定,记录会议室预定情况。
- 疫情期间,收集居民行程信息,收集居民身体指标等。
这些对话场景,你可以通过“表格写入单元”来实现。
下面开始介绍表格写入单元的相关内容。
在表格读取单元中,我们已经知道“定位列”、“定位值”的作用。
让我们回顾下,“定位列”即用于定位查询条件中某一列的列名,“定位值”为用于定位查询条件中某一行的值,我们把它们合并称为“定位条件”。
要更好的使用表格写入单元,除“定位列”、“定位值”之外,你还需要学习两个新概念:
写入列:用于定位将收集到的信息,写入到某一列的列名。你可以将所有的属性列作为写入列。
写入词槽:用于保存写入信息的词槽,即保存收集到的信息的词槽。
使用表格写入流程分为两个步骤:
在[表格数据]中,创建表格,并完成表头设置。用于表格写入时,对定位列和写入列的配置。
在任务流程中添加表格写入单元,配置关键条件,根据定位列和写入列,将收集到的信息保存在词槽中,并写入表格指定列。
表格写入支持选择“新增行”和“更新属性值”两种模式,分别对应表格的“新增行”和“修改值”。下面分别将对应的操作。
表格写入单元基本配置步骤如下:
1 点击左侧对话单元菜单中的“表格写入单元”,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 选择表格,选择要写入到的表格名称。
4 设置单元名称,通常结合任务对话流程进行设置,如:写入员工信息。
5 根据要实现的场景,选择写入模式:
更新属性值:用于更改写入属性值的配置模式,该模式的写入列只能选择属性列,不支持选择主体列。
新增行:即在表格中插入一行新数据。
更新属性值模式配置
设置定位列信息:
定位列列名:设置定位列的列名。支持手动输入、下拉选择列名进行输入、点击输入框右侧词槽进行输入。
定位值:支持输入一个固定的值作为定位值。也支持点击输入框右侧词槽进行输入,以词槽动态获取到的值作为定位值。
最多支持添加10组定位列,作为定位条件。多组定位列之间为“且”的关系。
设置写入列信息:
写入列列名:设置定位列的列名。仅支持设置为“属性列”列名。支持手动输入、下拉选择列名进行输入、点击输入框右侧词槽进行输入。
写入词槽:用于保存写入信息的词槽。支持下拉选择词槽。当要使用的词槽不存在时,可以点击“新建词槽”,新建后再进行使用。
最多支持添加10组写入列。
新增行模式配置
设置写入主体值信息:
- 选择主体值词槽:用于保存主体值的词槽。设置定位列的列名。支持手动输入、下拉选择列名进行输入、点击输入框右侧词槽进行输入。
设置写入列信息:
写入列列名:设置定位列的列名。仅支持设置为“属性列”列名。支持手动输入、下拉选择列名进行输入、点击输入框右侧词槽进行输入。
写入词槽:用于保存写入信息的词槽。支持下拉选择词槽。当要使用的词槽不存在时,可以点击“新建词槽”,新建后再进行使用。
最多支持添加10组写入列。
6 设置跳转关系。
- 分别选择写入成功和写入失败时的跳转单元。你也可以在画布中连线,进行跳转关系的设置。
7 点击单元详情右上角的保存。
以上就完成了一个表格写入单元的基本设置。
FAQ
Q1:更新值模式下,如果写入值的保存词槽没有获取到值,这种情况,定位列和写入列都配置正确的情况下,是清空值还是保留原属性值?
- A1: 清空。写入值的保存词槽未获取到值 和 未配置写入值的词槽 两种情况,都会清空原属性值。
Q2:更新值模式下,当写入列配置了多组,仅有一组写入列的写入值词槽获取到了值,这种情况,其他未获取到值的词槽对应的表格的属性值是保留还是清空?
- A2:获取到值的写入到属性中,其他列清空。
5.8.10属性读取单元
假设有这样一种场景:在用户查询机票信息时,机器人先去了解用户是否是会员。对会员用户除了返回航班信息外,还返回航班能产生多少会员积分,实现下面的效果:
对话示例
对于非会员用户:
用户A:帮我定明天的航班AA123 (机器人读取到用户A的身份是非会员)
机器人:好的,已经为您提交订单。祝您旅途愉快。
对于会员用户:
用户B:帮我定明天的航班AA123 (机器人读取到用户B的身份是会员)
机器人:好的,已经为您提交订单。同时您的会员积分已经更新为13620分。
这样的对话交互可以通过使用属性读取单元来实现。
在使用属性读取单元之前,你需要先计划好需要使用的[用户属性]。
比如,在上面提到的例子中,需要完成以下步骤:
- 到用户属性页面创建自定义属性“身份”,并定义属性值可以是“会员“或”非会员”。
- 创建词槽“是否会员”。
接下来,就可以进入意图中添加属性读取单元了。
1 点击左侧对话单元菜单中的属性读取单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称。
4 选择属性类型。可以选择预设属性,或自定义属性。
5 选择属性名称。比如,在上述例子中,这里选择“身份”。
6 选择用来保存这个属性的词槽。比如,在上述例子中,这里选择“是否会员”。
7 如果需要,可以点击添加一组,选择多个属性并把它们保存在多个词槽中。最多可以读取10个属性。
8 设置跳转关系。在需要跳转的单元中选择当属性读取完成后,需要进入的下一个单元。
9 点击单元详情右上角的保存。这样就完成了一个单元的基本设置。
5.8.11属性写入单元
假设有这样一种场景:在定机票的流程结尾,你希望将提交了订单、但目前是非会员的用户自动升级为会员,那么就可以使用属性写入单元,将用户的用户属性“会员/非会员”改为会员。
这样的对话交互可以通过使用属性写入单元来实现。
在使用属性写入单元之前,要先想好所需使用的[用户属性]。
比如,在上面提到的例子中,需要完成以下步骤:
- 到用户属性页面创建自定义属性“身份”,并定义属性值可以是“会员“或”非会员”。
- 创建词槽“是否会员”。
接下来,就可以进入意图中添加属性写入单元了。
1 点击左侧对话单元菜单中的属性写入单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称。
4 选择哪个词槽的值将用于写入到用户属性中。比如,在上文的例子中,这里选择“是否会员”。
5 选择属性类型。可以选择预设属性,或自定义属性。
6 选择被写入的属性名称。比如,在上文的例子中,这里选择“身份”。
7 如果需要,可以点击添加一组,选择多个属性并把它们保存在多个词槽中。最多可以写入10个属性。
8 设置跳转关系。在需要跳转的单元中选择当属性写入完成后,需要进入的下一个单元。
9 点击单元详情右上角的保存。这样就完成了一个单元的基本设置。
5.8.12意图终点单元
当一个意图流程执行完成后,机器人可能需要跳转到其他流程。或者,机器人可能需要判断是立即终结流程,还是保留当前的会话、等待用户随时回到会话中来。
这时,你就可以使用意图终点单元。
保留词槽
在意图执行完成后,可以保留词槽或者不保留。
- 保留词槽意味着:当意图执行完成后,保留当前的会话、等待用户随时回到会话中来。在意图的闲置等待时长内,用户发消息时会继续执行该意图;
对话示例
机器人:请输入姓名
用户:张三
机器人:请输入年龄
用户:20岁
机器人:收到信息如下:姓名:张三;年龄:20.00。
用户:说错了,是25岁。
机器人:收到信息如下:姓名:张三;年龄:25.00。
- 不保留词槽意味着:当意图执行完成后,立即终结流程。在意图的闲置等待时长内,用户发消息时意图流程需要被再次触发才能执行。
对话示例
机器人:请输入姓名
用户:张三
机器人:请输入年龄
用户:20岁
机器人:收到信息如下:姓名:张三;年龄:20.00。
用户:说错了,是25岁。
机器人:对不起,我还不会回答你的问题,请再说一次。 (兜底回复)
在意图设置中、和每个意图终点单元中,都有保留词槽的开关。
- 意图终点单元中的“在当前单元保留词槽”只控制这个单元的是否保留词槽。
- 意图设置中的“保留词槽”控制整个意图。
当意图设置中的“保留词槽”和意图终点单元中的“在当前单元保留词槽”不同的时候,如果流程运行到了意图终点单元,那么以意图终点单元中的设置为准。
提示: 词槽值能够保留多长时间,还与词槽设置中的生命周期、以及是否在意图的闲置等待时长内有关。
管理是否保留当前的会话
在默认设置中,意图终点单元中的“在当前单元保留词槽”是开启的。如果需要在流程走到当前意图终点单元时,结束会话,那么可以关闭该选项。
1 点击左侧对话单元菜单中的静默填槽单元,或拖拽到画布上。
2 点击编辑图标,打开单元详情。
3 输入单元名称。
4 在跳转意图的模式中,选择指定意图,并将意图名称设置为空。
5 选择在当前单元保留词槽。
6 点击单元详情右上角的保存。
跳转后的意图从头运行
- 如果意图B已经走到了结束单元,那么当意图A再次跳转到意图B时,意图B会从开始单元重新运行。
- 如果意图B为走到结束单元就被中断,进入闲置等待时长。那么
- 当意图A再次跳转到意图B时,不开启“跳转后的意图从头运行”,意图B从上一次结束的地方继续往后运行。
- 当意图A再次跳转到意图B时,开启“跳转后的意图从头运行”,意图B从开始单元重新运行。
5.9特殊配置
5.9.1利用意图终点单元构造“公用意图”
假设有这样一种场景:有三个意图,每个意图中是一个活动的报名流程。这三个意图的末尾都需要收集用户的姓名、城市、手机号。
如果我们在每个意图中都添加:
- 1个询问填槽单元用于收集用户姓名,
- 1个询问填槽单元用于收集所在城市,
- 1个询问填槽单元用于收集手机号,
那么就需要在三个意图中都创建重复的3个单元。比如,“报名流程1”就会是如下的效果:
这样操作有两个缺点:
- 在三个意图中重复创建三组单元,花费较多的精力。
- 当需要更新询问姓名的询问语句时,就需要在三个意图中分别更新。这样操作不利于对意图的管理。
在这样的场景下,就可以将三个通用的询问填槽单元放入一个独立的意图,命名为“收集信息”。这个意图专门用于收集用户资料。同时,在原来三个意图的末尾使用一个意图终点单元来跳转到“收集信息”。
1 创建一个“收集信息“意图。
2 添加询问填槽单元用于收集用户姓名。
3 添加询问填槽单元用于收集所在城市。
4 添加询问填槽单元用于收集手机号。
5 发布意图。
6 回到意图列表中,将“收集信息“意图的生效状态设置为“已生效”。
7 打开“报名流程1”意图。
8 添加一个意图终点单元,选择跳转到指定意图,在下拉列表中选择“收集信息”。
9 发布意图。
10 用同样的方式修改“报名流程2”和“报名流程3”。
从“公用意图”跳回原意图
在上面提到的“收集信息”的意图中,您可能还希望在收集用户资料之后,回到原来的意图继续流程。这个时候你面临的问题是:三个报名流程都有可能触发了这个“收集信息“的意图。机器人此时如何判断应该跳转回哪一个报名流程呢?
这种情况下,就可以使用跳转到上一个意图的功能。不论“收集信息”的意图是通过哪一个报名流程触发的,在它执行完成后,都可以跳回之前的意图。
1 在“收集信息“意图中添加一个意图终点单元。
2 选择跳转到上一个意图。
配置跳转后的起始单元
在一些场景中,意图B在之前已经被触发过,并且仍在闲置等待时长中。
- 如果意图B已经走到了结束单元,那么当意图A再次跳转到意图B时,意图B会从开始单元重新运行。
- 如果意图B为走到结束单元就被中断,进入闲置等待时长。那么
- 当意图A再次跳转到意图B时,不开启“跳转后的意图从头运行”,意图B从上一次结束的地方继续往后运行。
- 当意图A再次跳转到意图B时,开启“跳转后的意图从头运行”,意图B从开始单元重新运行。
注意: 这个配置只控制了跳转后意图的开始单元,但不控制词槽变化。
5.9.2填槽句式
在一些业务场景下,用户在一句话中会包含多个要收集的同类信息,且信息的顺序是不可混淆的。
比如,当机器人说:“请问您从哪个城市出发,到哪里?”的时候,用户可能有以下两种回复:
对话示例
用户1:北京到上海。
用户2:去北京,从上海出发。
在这个例子中,每位用户的消息里都包含了2个同类信息:北京和上海都是“城市”。尽管在两个句子中,“北京”都在前,“上海”都在后,但两个句子却表达了不同但出发城市和到达城市。
对话示例
在用户1的消息中:出发城市=北京,到达城市=上海。
在用户2的消息中:出发城市=上海,到达城市=北京。
由于对话单元的先后顺序在意图流程中是固定的(即,画布上的连线顺序),于是,对于意图中的设置我们有两种选择:
1 询问出发城市的对话单元在前,询问到达城市的在后。
根据这样的顺序,机器人从两个用户回复抽取到的信息分别为:
对话示例
用户1:北京到上海。
抽取到的信息: 出发城市=北京,到达城市=上海。✅
用户2:去北京,从上海出发。
抽取到的信息: 出发城市=北京,到达城市=上海。❌
2 询问到达城市的对话单元在前,询问出发城市的在后。
根据这样的顺序,机器人从两个用户回复抽取到的信息分别为:
对话示例
用户1:北京到上海。
抽取到的信息: 出发城市=上海,到达城市=北京。❌
用户2:去北京,从上海出发。
抽取到的信息: 出发城市=上海,到达城市=北京。✅
可以看到,这两种回复总是无法同时正确地抽取信息。
填槽句式就是用来解决此类问题的。这时,你可以通过添加以下两个句式、分别规定接收到用户不同说法时的两种填槽顺序:
句式1: @出发城市:城市 到 @到达城市:城市
句式2: 去 @到达城市:城市, 从 @出发城市:城市 出发
在上述语法格式中:“出发城市”、“到达城市”是词槽,词槽前用@符号表示。“城市”是实体,实体前用:符号与词槽分隔。关于句式的语法,在下文句式语法中会详细介绍。
有了以上两个句式,用户的两种回复就均可正确填槽,达到下面的效果:
对话示例
用户1:北京到上海。
抽取到的信息: 出发城市=北京,到达城市=上海。 ✅(匹配句式1)
用户2:去北京,从上海出发。
抽取到的信息: 出发城市=上海,到达城市=北京。 ✅(匹配句式2)
填槽句式是句式的一种用途。句式还可以用在意图触发器中,详情参考[意图管理]一章。在了解了填槽句式可以解决的问题之后,下面简单介绍下句式的概念以及它的多种用途。
句式
句式是通过使用词槽和实体来代表同类句子的句子模板。
句式的语法是:文本片段A @词槽名称1:实体名称11,实体名称12 文本片段B @词槽名称2:实体名称21 文本片段C
句式有两个用途:
用户触发的句式构建意图触发器中的模板,减少相似说法的数量。详情参考[意图管理]。
规定句子中多个相同实体的填槽顺序(即,本章节中介绍的用法)。
假设在同一个场景中有意图A、意图B,而且:
- 意图A的触发器中有句式1.
- 意图B的触发器中有句式2.
- 填槽句式中有句式3.
那么,句式1、2、3的作用范围如下:
句式 | 是否能触发意图A | 是否影响意图A流程中的填槽顺序 | 是否能触发意图B | 是否影响意图B流程中的填槽顺序 |
---|---|---|---|---|
句式1 | 是 | 是 | 否 | 是 |
句式2 | 否 | 是 | 是 | 是 |
句式3 | 否 | 是 | 否 | 是 |
下面介绍如何创建一个填槽句式:
1 点击新建句式。
2 在弹窗内编辑句式。
3 在需要插入词槽和实体的位置,输入@符号。此时会自动弹出选择词槽和选择实体的窗口。
4 点击选择词槽。
- 在激活的词槽下拉列表中选中一个词槽。
- 被选中的词槽的关联实体会自动出现在选择实体的区域。
- 如果需要,可点击选择实体增加更多实体。
- 如果需要,可点击实体上的x符号减少实体。
5 点击确定,即可将当前选择的词槽和实体加入词槽。
6 词槽和实体会出现在句式中。并高亮标示。
7 继续输入句式的其他内容。如果需要向句式中添加另一个词槽,再次输入@符号调出择词槽和选择实体的窗口。
8 完成句式编辑后,点击确定。句式就会出现在列表中。
5.9.3利用“闲置等待机制”实现多个“意图”的穿插
试想一下,你的终端用户正在和你的机器人对话。当机器人询问终端用户一个问题时,终端用户可能并没有马上回复。这种情况在真实对话中很常见。
此时,你可能希望机器人停在这里等待用户。如果用户隔了一段时间回复了,那么,对话流程还能够继续执行。如果用户始终没有回复,则机器人在一段时间之后结束对话。
为了让机器人有“暂停”某个意图去等待一些事件的发生,平台支持闲置等待机制。可以使用该机制的情况包括:
机器人询问后,用户未及时应答。
其他意图打断了当前意图。平台允许在当前意图运行的过程中被另一个意图打断,进而运行“另一个意图”。
常见的“意图打断”的情况1:“用户消息触发了其他意图”。
常见的“意图打断”的情况2:意图中配置了“跳转意图”单元
意图流程中触发了问答式对话。
两类闲置等待时间:
“场景”层级的闲置等待时间:对该场景下所有意图生效。
“意图”层级的闲置等待时间:只对当前意图有效。
“闲置等待时长”的计算方法
一个意图的闲置等待时长由以下两者决定:
计时起点:在这个意图流程中,用户最后一次与机器人进行交互的时间。
闲置等待时长:取如下两个数字中的最小值:该意图的闲置等待时长、意图所在场景的闲置等待时长。
比如,用户在20点00分最后一次与机器人交互。意图的闲置等待时长为3分钟,意图所在场景的闲置等待时长为10分钟。那么:
如果在20点03分之前,用户没有再次与机器人交互,当前这个意图流程结束。
如果在20点03分之前,用户再次与机器人交互,机器人就从之前停下来的流程节点继续执行。
“闲置等待”的效果
“闲置等待”机制的效果:假设因任何一种情况,当前意图“被暂停”。那么,从计时起点开始:
如果在闲置等待时长内,回到当前意图,则流程会从原来“被暂停”的位置开始,继续向后执行。
如果超出闲置等待时长,那么
- A、当前意图对应的流程将中止;
- B、之前收集到的信息将被清空;
- C、用户消息必须匹配到意图触发器才会再次回到该意图中;
- D、对话将从意图流程的起点开始执行。
操作指南
1 在系统上,设置意图的”闲置等待时长“的步骤为:
- 点击意图设置。
- 输入期望的“闲置等待时长”并保存。
2 设置场景的”闲置等待时长“的步骤为:
- 点击场景卡片上的设置图标。
- 在弹窗内,输入期望的“闲置等待时长”并保存。
5.9.4“填槽优先”的策略
在对话中可能出现这样的冲突情况:一个意图流程已经在进行的过程中,用户说了一句话,既可以回答单元的询问,又可以触发另一个意图。这个时候,机器人就需要决策是执行当前流程,还是切换到另一个意图的流程。
系统中对这种的冲突采取以下策略:
1 如果当前已经有正在运行中的意图,比如意图A,则尝试抽取用户消息去填充意图A当前单元的词槽。
如果可以填充,则填槽并根据词槽判断后续流程。
如果不可以填充,则判断用户消息是否可以匹配到其他意图的触发器。
如果可以,则触发置信度得分最高的意图。
如果不可以,则任务对话不对该条用户消息做回应。
2 如果当前没有正在运行中的意图,则尝试将用户消息匹配所有意图触发器。
如果匹配到了,则触发置信度得分最高的意图。
如果没有匹配到,则任务对话不对该条用户消息做回应。
5.9.5函数操作词槽值
在上面的例子中,如果查询到的结果只有一个的话,我们可以直接在消息中插入{slot=词槽名},在对话时把获取到的词槽的值填入话术中发给用户。
然而,在读表时,有时需要查到多个结果展示出来,甚至针对多个结果做一些加工再展示。例如:
1 展示查询到的多个结果:
对话示例
⽤户:“公司里有哪些产品经理?”
机器人:“产品经理有张三、李四、王五。”
2 查询到多个结果,找到其中的最大值并展示:
对话示例
用户:“收益率最高的基金是哪个?”
机器人:“收益率最高的是XX基金,年化收益率8%”
这些情况难以⽤简单地插入词槽到⽂本当中解决。对此,平台提供一些简单的函数,可以用这些函数:
格式化地展示多值词槽
对多值词槽做一些运算
函数可以在机器人回复(消息单元&询问单元)、运算单元拼接模式生效。一般情况下在机器人回复里直接用,复杂需求可以在拼接模式⾥赋值到词槽。
下面介绍⽬前支持的函数。
5.9.5.1格式化展示操作符(JOIN)
利用JOIN操作符可以对返回值进行格式化的展示。
语法:[[JOIN:content,begin=\d+,len=\d+,split=.+]]
作用:格式化展示一个或多个词槽中的值。
参数:
content:必须。要格式化展示的内容,里⾯可以插⼊词槽。
begin:⾮必须。整数字,最⼩是1,表示展示的时候从第几个开始。
len:⾮必须。整数字,表示从begin位置往后展示多少个。
split:⾮必须。任意字符,表示前后两个词槽值之间的分隔符。
平台操作
案例一:返回列只有一个,能返回多个值,需要展示所有值。
对话示例
用户:“公司⾥有哪些产品经理?”
机器人:“产品经理有张三、李四、王五。”
对应的读表配置:
定位列:职位
定位值:产品经理
返回列:姓名
保存词槽:姓名
回复配置:
话术⽂本中插入查询到的所有值,若值之间用“、”分隔。则消息单元可以这样配置:
产品经理有 [[JOIN:{slot=姓名},split=、]]。
案例二:返回列只有一个,能返回多个值,只需要展示其中2个值。
对话示例
用户:“公司里有哪些产品经理?”
机器人:“产品经理有张三、李四等人。”
对应的读表配置:
定位列:职位
定位值:产品经理
返回列:姓名
保存词槽:姓名
回复配置:
话术文本中插入查询到的所有值中的前两个,值之间用“、”分隔。则消息单元可以这样配置:
产品经理有[[JOIN:{slot=姓名},begin=1,len=2,split=、]]等人。
5.9.5.2取词槽最大值(MAX)
取“xx词槽”的多个值中,最大的一个值。
语法:[[MAX:{slot=xx词槽}]]
作用:当词槽获取到的是多值时,
参数:
- slot:必须。代表找那个词槽里的最大值,词槽最多选⼀个。
可以取到词槽多个值中,最大的一个。(如果词槽⾥不是纯数字,就给出字符串比较的结果)
平台操作
案例一:返回列返回多个值时,只展示其中最大的一个。
对话示例
用户:“基金收益最高能有多少?”
机器人:“⽬前收益最高的是年化30%。”
对应的读表配置:
定位列:基金名称
定位值:空(不填代表返回所有)
返回列:年化收益
保存词槽:年化收益
回复配置:
返回所有产品的年化收益,但是只展示最高的收益是多少。则消息单元可以这样配置:
目前收益最高的是年化[[MAX:{slot=年化收益}]]%
案例二:返回列返回多个值时,只展示其中最大的一个,以及最大值对应的相关信息。
对话示例
用户:“基金收益最高的是哪个?”
机器人:“目前收益最高的是大奖章一号,年化30%。”
对应的读表配置(需要两次读表):
第一次:读取所有年化收益
定位列:基金名称
定位值:空(不填代表返回所有)
返回列:年化收益
保存词槽:年化收益
第二次:用最高年化收益,定位到对应的基金
定位列:年化收益
定位值:[[MAX:{slot=年化收益}]]
返回列:基金名称
保存词槽:基金名称
回复配置:
返回所有产品的年化收益,但是只展示最高的。消息单元可这样配置:
目前收益最高的是{slot=基金名称},年化[[MAX:{slot=年化收益}]]%
5.9.5.3取词槽最小值(MIN)
取“xx词槽”中多个值中,最小的一个值。
语法:[[MIN:{slot=xx词槽}]]
参数:
- slot:必须。代表找那个词槽里的最小值,词槽最多选一个。
可以取到词槽多个值中,最小的一个。如果词槽里不是纯数字,就给出字符串比较的结果。
配置操作方法同MAX,案例略。
5.9.5.4取词槽值数量(COUNT)
取xx词槽中,里面值的总数(即读表单元拿到了多少结果)。
语法:[[COUNT:{slot=xx词槽}]]
参数:
- slot:必须。要操作的词槽,最多选一个。 可以取到词槽里有多少个值。不做去重。
平台操作
案例一:返回列返回多个值,展示值的数量。
对话示例
用户:“公司现在有多少人?”
机器人:“目前公司总共有1000人”
对应的读表配置:
定位列:员工姓名
定位值:空(不填代表返回所有)
返回列:员工姓名(其实用哪一列都可以,因为只需要数有多少行)
保存词槽:员工姓名
回复配置:
目前公司总共有[[COUNT:{slot=员工姓名}]]人
5.9.5.5取词槽平均值(AVG)
取xx词槽中,里面值的总数(即读表单元拿到了多少结果)。
语法:[[AVG:{slot=xx词槽}]]
参数:
- slot:必须。要操作的词槽,最多选一个。
平台操作
案例一:返回列返回多个值,展示值的平均值。
对话示例
用户:“公司目前平均年龄多少?”
机器人:“目前公司平均年龄为28.6666667岁”
对应的读表配置:
定位列:员工姓名
定位值:空(不填代表返回所有)
返回列:年龄
保存词槽:年龄
回复配置:
目前公司平均年龄为[[AVG:{slot=年龄}]]岁
5.9.5.6产生随机数(RAND)
产生[begin,end]内的一个整数随机数。
语法:[[RAND:begin,end]]
参数:
begin:必填,整数。产生的随机数的最小值。可以是{slot=词槽xx}
end:必填,整数。产生的随机数的最大值。可以是{slot=词槽xx}
平台操作
案例一:趣味答题,利用读表单元随机从表格中获取题目。
对话示例
用户:“抽一道题”
机器人:“题目3”
用户:“抽一道题” 机器人:“题目2” ……(每次都随机抽)
对应的读表配置:
定位列:题目编号
定位值:[[RAND:1,100]](假设题目编号是1到100)
返回列:问题内容
保存词槽:问题内容
回复配置:
{slot=问题内容}
5.9.5.7对词槽去重(DISTINCT)
对有多个值的词槽进行去重。
语法:[[DISTINCT:{slot=target}]]
参数:
- slot:必须。要操作的词槽,最多选一个。
平台操作
案例一:格式化展示去重后的结果。
分两步:
1 查找某一列所有可能的值,并去重。
2 格式化展示去重后的结果。
对话示例
用户:“公司现在有哪些部门?”
机器人:“目前公司的所有部门有:市场部、产品部、技术部”
对应的读表配置:
1 用读表单元读取部门列的所有内容:
定位列:空(不填代表返回所有)
定位值:空(不填代表返回所有)
返回列:部门
保存词槽:部门
2 借助运算单元和函数对部门词槽去重:
- 模式:拼接模式
- 拼接内容:[[DISTINCT:{slot=部门}]]
- 关联词槽:部门
回复配置:
目前公司的所有部门有:[[JOIN:{slot=部门},split=、]]。